﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace Msdn5.Framework
{
    public static class RandomString
    {
        static Random rand = new Random(Environment.TickCount);
        #region 生僻字

        static string CnWords = "亍丌兀丐廿卅丕亘丞鬲孬噩丨禺丿匕乇夭爻卮氐囟胤馗毓睾鼗丶亟鼐乜乩亓芈孛啬嘏仄厍厝厣厥厮靥赝匚叵匦匮匾赜卦卣刂刈刎刭刳刿剀剌剞剡剜蒯剽劂劁劐劓冂罔亻仃仉仂仨仡仫仞伛仳伢佤仵伥伧伉伫佞佧攸佚佝佟佗伲伽佶佴侑侉侃侏佾佻侪佼侬侔俦俨俪俅俚俣俜俑俟俸倩偌俳倬倏倮倭俾倜倌倥倨偾偃偕偈偎偬偻傥傧傩傺僖儆僭僬僦僮儇儋仝氽佘佥俎龠汆籴兮巽黉馘冁夔勹匍訇匐凫夙兕亠兖亳衮袤亵脔裒禀嬴蠃羸冫冱冽冼凇冖冢冥讠讦讧讪讴讵讷诂诃诋诏诎诒诓诔诖诘诙诜诟诠诤诨诩诮诰诳诶诹诼诿谀谂谄谇谌谏谑谒谔谕谖谙谛谘谝谟谠谡谥谧谪谫谮谯谲谳谵谶卩卺阝阢阡阱阪阽阼陂陉陔陟陧陬陲陴隈隍隗隰邗邛邝邙邬邡邴邳邶邺邸邰郏郅邾郐郄郇郓郦郢郜郗郛郫郯郾鄄鄢鄞鄣鄱鄯鄹酃酆刍奂劢劬劭劾哿勐勖勰叟燮矍廴凵凼鬯厶弁畚巯坌垩垡塾墼壅壑圩圬圪圳圹圮圯坜圻坂坩垅坫垆坼坻坨坭坶坳垭垤垌垲埏垧垴垓垠埕埘埚埙埒垸埴埯埸埤埝堋堍埽埭堀堞堙塄堠塥塬墁墉墚墀馨鼙懿艹艽艿芏芊芨芄芎芑芗芙芫芸芾芰苈苊苣芘芷芮苋苌苁芩芴芡芪芟苄苎芤苡茉苷苤茏茇苜苴苒苘茌苻苓茑茚茆茔茕苠苕茜荑荛荜茈莒茼茴茱莛荞茯荏荇荃荟荀茗荠茭茺茳荦荥荨茛荩荬荪荭荮莰荸莳莴莠莪莓莜莅荼莶莩荽莸荻莘莞莨莺莼菁萁菥菘堇萘萋菝菽菖萜萸萑萆菔菟萏萃菸菹菪菅菀萦菰菡葜葑葚葙葳蒇蒈葺蒉葸萼葆葩葶蒌蒎萱葭蓁蓍蓐蓦蒽蓓蓊蒿蒺蓠蒡蒹蒴蒗蓥蓣蔌甍蔸蓰蔹蔟蔺蕖蔻蓿蓼蕙蕈蕨蕤蕞蕺瞢蕃蕲蕻薤薨薇薏蕹薮薜薅薹薷薰藓藁藜藿蘧蘅蘩蘖蘼廾弈夼奁耷奕奚奘匏尢尥尬尴扌扪抟抻拊拚拗拮挢拶挹捋捃掭揶捱捺掎掴捭掬掊捩掮掼揲揸揠揿揄揞揎摒揆掾摅摁搋搛搠搌搦搡摞撄摭撖摺撷撸撙撺擀擐擗擤擢攉攥攮弋忒甙弑卟叱叽叩叨叻吒吖吆呋呒呓呔呖呃吡呗呙吣吲咂咔呷呱呤咚咛咄呶呦咝哐咭哂咴哒咧咦哓哔呲咣哕咻咿哌哙哚哜咩咪咤哝哏哞唛哧唠哽唔哳唢唣唏唑唧唪啧喏喵啉啭啁啕唿啐唼唷啖啵啶啷唳唰啜喋嗒喃喱喹喈喁喟啾嗖喑啻嗟喽喾喔喙嗪嗷嗉嘟嗑嗫嗬嗔嗦嗝嗄嗯嗥嗲嗳嗌嗍嗨嗵嗤辔嘞嘈嘌嘁嘤嘣嗾嘀嘧嘭噘嘹噗嘬噍噢噙噜噌噔嚆噤噱噫噻噼嚅嚓嚯囔囗囝囡囵囫囹囿圄圊圉圜帏帙帔帑帱帻帼帷幄幔幛幞幡岌屺岍岐岖岈岘岙岑岚岜岵岢岽岬岫岱岣峁岷峄峒峤峋峥崂崃崧崦崮崤崞崆崛嵘崾崴崽嵬嵛嵯嵝嵫嵋嵊嵩嵴嶂嶙嶝豳嶷巅彳彷徂徇徉後徕徙徜徨徭徵徼衢彡犭犰犴犷犸狃狁狎狍狒狨狯狩狲狴狷猁狳猃狺狻猗猓猡猊猞猝猕猢猹猥猬猸猱獐獍獗獠獬獯獾舛夥飧夤夂饣饧饨饩饪饫饬饴饷饽馀馄馇馊馍馐馑馓馔馕庀庑庋庖庥庠庹庵庾庳赓廒廑廛廨廪膺忄忉忖忏怃忮怄忡忤忾怅怆忪忭忸怙怵怦怛怏怍怩怫怊怿怡恸恹恻恺恂恪恽悖悚悭悝悃悒悌悛惬悻悱惝惘惆惚悴愠愦愕愣惴愀愎愫慊慵憬憔憧憷懔懵忝隳闩闫闱闳闵闶闼闾阃阄阆阈阊阋阌阍阏阒阕阖阗阙阚丬爿戕汔汜汊沣沅沐沔沌汨汩汴汶沆沩泐泔沭泷泸泱泗沲泠泖泺泫泮沱泓泯泾洹洧洌浃浈洇洄洙洎洫浍洮洵洚浏浒浔洳涑浯涞涠浞涓涔浜浠浼浣渚淇淅淞渎涿淠渑淦淝淙渖涫渌涮渫湮湎湫溲湟溆湓湔渲渥湄滟溱溘滠漭滢溥溧溽溻溷滗溴滏溏滂溟潢潆潇漤漕滹漯漶潋潴漪漉漩澉澍澌潸潲潼潺濑濉澧澹澶濂濡濮濞濠濯瀚瀣瀛瀹瀵灏灞宀宄宕宓宥宸甯骞搴寤寮褰寰蹇謇辶迓迕迥迮迤迩迦迳迨逅逄逋逦逑逍逖逡逵逶逭逯遄遑遒遐遨遘遢遛暹遴遽邂邈邃邋彐彗彖彘尻咫屐屙孱屣屦羼弪弩弭艴弼鬻屮妁妃妍妩妪妣妗姊妫妞妤姒妲妯姗妾娅娆姝娈姣姘姹娌娉娲娴娑娣娓婀婧婊婕娼婢婵胬媪媛婷婺媾嫫媲嫒嫔媸嫠嫣嫱嫖嫦嫘嫜嬉嬗嬖嬲嬷孀尕尜孚孥孳孑孓孢驵驷驸驺驿驽骀骁骅骈骊骐骒骓骖骘骛骜骝骟骠骢骣骥骧纟纡纣纥纨纩纭纰纾绀绁绂绉绋绌绐绔绗绛绠绡绨绫绮绯绱绲缍绶绺绻绾缁缂缃缇缈缋缌缏缑缒缗缙缜缛缟缡缢缣缤缥缦缧缪缫缬缭缯缰缱缲缳缵幺畿巛甾邕玎玑玮玢玟珏珂珑玷玳珀珉珈珥珙顼琊珩珧珞玺珲琏琪瑛琦琥琨琰琮琬琛琚瑁瑜瑗瑕瑙瑷瑭瑾璜璎璀璁璇璋璞璨璩璐璧瓒璺韪韫韬杌杓杞杈杩枥枇杪杳枘枧杵枨枞枭枋杷杼柰栉柘栊柩枰栌柙枵柚枳柝栀柃枸柢栎柁柽栲栳桠桡桎桢桄桤梃栝桕桦桁桧桀栾桊桉栩梵梏桴桷梓桫棂楮棼椟椠棹椤棰椋椁楗棣椐楱椹楠楂楝榄楫榀榘楸椴槌榇榈槎榉楦楣楹榛榧榻榫榭槔榱槁槊槟榕槠榍槿樯槭樗樘橥槲橄樾檠橐橛樵檎橹樽樨橘橼檑檐檩檗檫猷獒殁殂殇殄殒殓殍殚殛殡殪轫轭轱轲轳轵轶轸轷轹轺轼轾辁辂辄辇辋辍辎辏辘辚軎戋戗戛戟戢戡戥戤戬臧瓯瓴瓿甏甑甓攴旮旯旰昊昙杲昃昕昀炅曷昝昴昱昶昵耆晟晔晁晏晖晡晗晷暄暌暧暝暾曛曜曦曩贲贳贶贻贽赀赅赆赈赉赇赍赕赙觇觊觋觌觎觏觐觑牮犟牝牦牯牾牿犄犋犍犏犒挈挲掰搿擘耄毪毳毽毵毹氅氇氆氍氕氘氙氚氡氩氤氪氲攵敕敫牍牒牖爰虢刖肟肜肓肼朊肽肱肫肭肴肷胧胨胩胪胛胂胄胙胍胗朐胝胫胱胴胭脍脎胲胼朕脒豚脶脞脬脘脲腈腌腓腴腙腚腱腠腩腼腽腭腧塍媵膈膂膑滕膣膪臌朦臊膻臁膦欤欷欹歃歆歙飑飒飓飕飙飚殳彀毂觳斐齑斓於旆旄旃旌旎旒旖炀炜炖炝炻烀炷炫炱烨烊焐焓焖焯焱煳煜煨煅煲煊煸煺熘熳熵熨熠燠燔燧燹爝爨灬焘煦熹戾戽扃扈扉祀祆祉祛祜祓祚祢祗祠祯祧祺禅禊禚禧禳忑忐怼恝恚恧恁恙恣悫愆愍慝憩憝懋懑戆肀聿沓泶淼矶矸砀砉砗砘砑斫砭砜砝砹砺砻砟砼砥砬砣砩硎硭硖硗砦硐硇硌硪碛碓碚碇碜碡碣碲碹碥磔磙磉磬磲礅磴礓礤礞礴龛黹黻黼盱眄眍盹眇眈眚眢眙眭眦眵眸睐睑睇睃睚睨睢睥睿瞍睽瞀瞌瞑瞟瞠瞰瞵瞽町畀畎畋畈畛畲畹疃罘罡罟詈罨罴罱罹羁罾盍盥蠲钅钆钇钋钊钌钍钏钐钔钗钕钚钛钜钣钤钫钪钭钬钯钰钲钴钶钷钸钹钺钼钽钿铄铈铉铊铋铌铍铎铐铑铒铕铖铗铙铘铛铞铟铠铢铤铥铧铨铪铩铫铮铯铳铴铵铷铹铼铽铿锃锂锆锇锉锊锍锎锏锒锓锔锕锖锘锛锝锞锟锢锪锫锩锬锱锲锴锶锷锸锼锾锿镂锵镄镅镆镉镌镎镏镒镓镔镖镗镘镙镛镞镟镝镡镢镤镥镦镧镨镩镪镫镬镯镱镲镳锺矧矬雉秕秭秣秫稆嵇稃稂稞稔稹稷穑黏馥穰皈皎皓皙皤瓞瓠甬鸠鸢鸨鸩鸪鸫鸬鸲鸱鸶鸸鸷鸹鸺鸾鹁鹂鹄鹆鹇鹈鹉鹋鹌鹎鹑鹕鹗鹚鹛鹜鹞鹣鹦鹧鹨鹩鹪鹫鹬鹱鹭鹳疒疔疖疠疝疬疣疳疴疸痄疱疰痃痂痖痍痣痨痦痤痫痧瘃痱痼痿瘐瘀瘅瘌瘗瘊瘥瘘瘕瘙瘛瘼瘢瘠癀瘭瘰瘿瘵癃瘾瘳癍癞癔癜癖癫癯翊竦穸穹窀窆窈窕窦窠窬窨窭窳衤衩衲衽衿袂裆袷袼裉裢裎裣裥裱褚裼裨裾裰褡褙褓褛褊褴褫褶襁襦疋胥皲皴矜耒耔耖耜耠耢耥耦耧耩耨耱耋耵聃聆聍聒聩聱覃顸颀颃颉颌颍颏颔颚颛颞颟颡颢颥颦虍虔虬虮虿虺虼虻蚨蚍蚋蚬蚝蚧蚣蚪蚓蚩蚶蛄蚵蛎蚰蚺蚱蚯蛉蛏蚴蛩蛱蛲蛭蛳蛐蜓蛞蛴蛟蛘蛑蜃蜇蛸蜈蜊蜍蜉蜣蜻蜞蜥蜮蜚蜾蝈蜴蜱蜩蜷蜿螂蜢蝽蝾蝻蝠蝰蝌蝮螋蝓蝣蝼蝤蝙蝥螓螯螨蟒蟆螈螅螭螗螃螫蟥螬螵螳蟋蟓螽蟑蟀蟊蟛蟪蟠蟮蠖蠓蟾蠊蠛蠡蠹蠼缶罂罄罅舐竺竽笈笃笄笕笊笫笏筇笸笪笙笮笱笠笥笤笳笾笞筘筚筅筵筌筝筠筮筻筢筲筱箐箦箧箸箬箝箨箅箪箜箢箫箴篑篁篌篝篚篥篦篪簌篾篼簏簖簋簟簪簦簸籁籀臾舁舂舄臬衄舡舢舣舭舯舨舫舸舻舳舴舾艄艉艋艏艚艟艨衾袅袈裘裟襞羝羟羧羯羰羲籼敉粑粝粜粞粢粲粼粽糁糇糌糍糈糅糗糨艮暨羿翎翕翥翡翦翩翮翳糸絷綦綮繇纛麸麴赳趄趔趑趱赧赭豇豉酊酐酎酏酤酢酡酰酩酯酽酾酲酴酹醌醅醐醍醑醢醣醪醭醮醯醵醴醺豕鹾趸跫踅蹙蹩趵趿趼趺跄跖跗跚跞跎跏跛跆跬跷跸跣跹跻跤踉跽踔踝踟踬踮踣踯踺蹀踹踵踽踱蹉蹁蹂蹑蹒蹊蹰蹶蹼蹯蹴躅躏躔躐躜躞豸貂貊貅貘貔斛觖觞觚觜觥觫觯訾謦靓雩雳雯霆霁霈霏霎霪霭霰霾龀龃龅龆龇龈龉龊龌黾鼋鼍隹隼隽雎雒瞿雠銎銮鋈錾鍪鏊鎏鐾鑫鱿鲂鲅鲆鲇鲈稣鲋鲎鲐鲑鲒鲔鲕鲚鲛鲞鲟鲠鲡鲢鲣鲥鲦鲧鲨鲩鲫鲭鲮鲰鲱鲲鲳鲴鲵鲶鲷鲺鲻鲼鲽鳄鳅鳆鳇鳊鳋鳌鳍鳎鳏鳐鳓鳔鳕鳗鳘鳙鳜鳝鳟鳢靼鞅鞑鞒鞔鞯鞫鞣鞲鞴骱骰骷鹘骶骺骼髁髀髅髂髋髌髑魅魃魇魉魈魍魑飨餍餮饕饔髟髡髦髯髫髻髭髹鬈鬏鬓鬟鬣麽麾縻麂麇麈麋麒鏖麝麟黛黜黝黠黟黢黩黧黥黪黯鼢鼬鼯鼹鼷鼽鼾齄";
        #endregion
        /// <summary>
        /// 随机生僻汉字
        /// </summary>
        /// <param name="len">生成的长度</param>
        /// <returns>随机生僻汉字</returns>
        public static string RnUnusualCnWords(this int len)
        {
            StringBuilder sbCode = new StringBuilder();
            for (int i = 0; i < len; i++)
            {
                char ch = CnWords[rand.Next(CnWords.Length)];
                sbCode.Append(ch);
            }
            return sbCode.ToString();
        }
        /// <summary>
        /// 随机中国汉字[\u4e00-\u9fa5]
        /// </summary>
        /// <param name="len">生成的长度</param>
        /// <returns>随机汉字</returns>
        public static string RnCnWords(this int len)
        {
            StringBuilder sbCode = new StringBuilder();
            for (int i = 0; i < len; i++)
            {
                string str = $"\\u{rand.Next(0x4e00, 0x9fa5).ToString("X")}".UnicodeDecoding();
                sbCode.Append(str);
            }
            return sbCode.ToString();
        }
        /// <summary>
        /// 创建随机字符串
        /// 去除 1 l i 0 o 等容易混淆的字符(可用于生成验证码)
        /// </summary>
        /// <param name="len">字符个数</param>
        /// <returns>返回的数据</returns>
        public static string RnString(this int len)
        {
            rand = new Random(Guid.NewGuid().GetHashCode());
            char[] data = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'k', 'm', 'p', 'r', 's', 't', 'w', 'x', 'y', '2', '3', '4', '5', '6', '7', '8' };
            StringBuilder sbCode = new StringBuilder();
            for (int i = 0; i < len; i++)
            {
                char ch = data[rand.Next(data.Length)];
                sbCode.Append(ch);
            }
            return sbCode.ToString();
        }
        /// <summary>
        /// 完全随机的字符串
        /// 包含大写字母/小写字母/数字
        /// </summary>
        /// <param name="length">字符串长度</param>
        /// <returns>随机字符串</returns>
        public static string RnLongString(this int length)
        {
            rand = new Random(Guid.NewGuid().GetHashCode());
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < length; i++)
            {

                //随机选择里面其中的一种字符生成
                switch (rand.Next(3))
                {
                    case 0:
                        sb.Append(3.RnNum(10));
                        break;
                    case 1:
                        sb.Append(LowerAbc());
                        break;
                    case 2:
                        sb.Append(UpperAbc());
                        break;
                }
            }
            return sb.ToString();
        }
        /// <summary>
        /// 随机长度字母
        /// </summary>
        /// <param name="length">长度</param>
        /// <param name="isUpper">是否大写,默认true</param>
        /// <returns>随机结果</returns>
        public static string RnABCString(this int length, bool isUpper = true)
        {

            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < length; i++)
            {
                sb.Append(isUpper ? UpperAbc() : LowerAbc());
            }
            return sb.ToString();
        }
        /// <summary>
        /// 生成单个随机数字
        /// </summary>  
        /// <param name="Min">最小默认0</param>
        /// <param name="Max">最大默认10</param>
        /// <returns>随机数字</returns>
        public static int RnNum(this int Min, int Max = 10)
        {
            rand = new Random(Guid.NewGuid().GetHashCode());
            return rand.Next(Min, Max);
        }

        /// <summary>
        /// 生成指定长度的随机数字数组
        /// </summary>
        /// <param name="Len">长度</param>
        /// <param name="Min">最小默认0</param>
        /// <param name="Max">最大默认10</param>
        /// <returns>随机数字</returns>
        public static int[] RnNums(this int Len, int Min = 0, int Max = 10)
        {
            int[] nums = new int[Len];
            for (int i = 0; i < Len; i++)
            {
                nums[i] = rand.Next(Min, Max);
            }
            return nums;
        }
        /// <summary>
        /// 随机生成Decimal
        /// </summary> 
        /// <param name="Min">最小默认0</param>
        /// <param name="Max">最大默认10</param>
        /// <returns></returns>
        public static decimal RnDecimal(this int Min, int Max = 10)
        {
            var rd = ((double)RnNum(Min, Max) + RnDouble());
            return (decimal)(rd);
        }
        /// <summary>
        /// 返回一个0.0-1.0之间的随机小数
        /// </summary>
        /// <returns>随机小数</returns>
        public static double RnDouble()
        {
            rand = new Random(Guid.NewGuid().GetHashCode());
            return rand.NextDouble();
        }
        /// <summary>
        /// 返回一个随机填充的bytes
        /// </summary>
        /// <param name="len">数组的长度</param>
        /// <returns>随机bytes</returns>
        public static byte[] RnBytes(this int len)
        {
            rand = new Random(Guid.NewGuid().GetHashCode());
            byte[] buffer = new byte[len];
            rand.NextBytes(buffer);
            return buffer;
        }
        /// <summary>
        /// 生成单个大写随机字母
        /// </summary>
        public static string UpperAbc()
        {
            //A-Z的 ASCII值为65-90 
            return Convert.ToChar(rand.Next(65, 91)).ToString();
        }

        /// <summary>
        /// 生成单个小写随机字母
        /// </summary>
        public static string LowerAbc()
        {
            //a-z的 ASCII值为97-122  
            return Convert.ToChar(rand.Next(97, 123)).ToString();
        }
        /// <summary>
        /// 下划线转驼峰命名法则
        /// 如: msdn5_admin => Msdn5Admin
        /// </summary>
        /// <param name="name">原始内容</param>
        /// <returns>转换后结果</returns>
        public static string HumpNamed(this string text)
        {
            text = Regex.Replace(text.TrimStart('@', '.'), @"[^\w]", "_");
            text = char.IsLetter(text, 0) ? text : string.Concat("_", text);
            text = string.Join("", text.Split('_').Select(a => FirstKeyUpper(a)));
            return text;
        }
        /// <summary>
        /// 下划线转JSON首字母小写驼峰
        /// 如: msdn5_admin => msdn5Admin
        /// </summary>
        /// <param name="text">原始内容</param>
        /// <returns>转换后结果</returns>
        public static string JsonHumpNamed(this string text)
        {
            var name = text.HumpNamed();
            var firstn = name[0].ToString().ToLower();
            name = name.Remove(0, 1).Insert(0, firstn);
            return name;
        }
        /// <summary>
        /// 去下划线首字母大写
        /// 如: msdn5_admin => Msdn5admin
        /// </summary>
        /// <param name="text">原始内容</param>
        /// <returns>转换后结果</returns>
        public static string FirstKeyUpper(this string text)
        {
            text = Regex.Replace(text, @"[^\w]", "_");
            if (text.Length <= 1) { text = text.ToUpper(); }
            else { text = text.Substring(0, 1).ToUpper() + text.Substring(1, text.Length - 1); }
            return text;
        }
        /// <summary>
        /// 去下划线首字母小写
        /// 如: msdn5_admin => msdn5Admin
        /// </summary>
        /// <param name="text">原始内容</param>
        /// <returns>转换后结果</returns>
        public static string FirstKeyLower(this string text)
        {
            text = Regex.Replace(text, @"[^\w]", "_");
            if (text.Length <= 1) { text = text.ToLower(); }
            else { text = text.Substring(0, 1).ToLower() + text.Substring(1, text.Length - 1); }
            return text;
        }
        /// <summary>
        /// 创建随机字符(GUID)
        /// </summary>
        /// <param name="len">字符个数</param>
        /// <returns>包含字母数字的GUID的字符串</returns>
        public static string GuidString(this int len)
        {
            string guid = string.Empty;
            if (len > 0 && len <= 32)
            {
                guid = GuidString().Substring(0, len);
            }
            else
            {
                if (len <= 0)
                {
                    //直接返回一个guid
                    guid = GuidString();
                }
                else
                {
                    //超过32位
                    int count = (int)Math.Ceiling((double)len / (double)32);
                    string tmp = "";
                    for (int i = 0; i < count; i++)
                    {
                        tmp += GuidString();
                    }
                    guid = tmp.Substring(0, len);
                }
            }
            return guid;
        }
        /// <summary>
        /// 创建随机字符(GUID)
        /// </summary>
        /// <returns>随机字符</returns>
        public static string GuidString()
        {
            return Guid.NewGuid().ToString("N");
        }

    }
}
